/* 
 * Cashbox is the legal property of its developers, whose names are listed in the copyright file included
 * with this source distribution.
 * 
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
 * General Public License as published by the Free Software Foundation; either version 2 of the License,
 * or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 * Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this program; if not,
 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#import "CBImportViewController.h"
#import "CBImporter.h"
#import "CBQIFImporter.h"
#import "CBImportAccount.h"
#import "CBImportLabel.h"
#import "ColorListColors.h"
#import "CBAccount.h"

#import "CBGeneralPreferenceViewController.h"

#define QIF_INFORMTION_URL		@"http://www.fadingred.org/cashbox/support/wiki/QIFDateInformation"

#define ACCOUNTS_TAB		0
#define LABELS_TAB			1
#define QIF_OPTIONS_TAB		2
#define ERRORS_TAB			3
#define PROGRESS_TAB		4

#define PROGRESS_WIDTH		388
#define PROGRESS_HEIGHT		91

#define STANDARD_WIDTH		453
#define STANDARD_HEIGHT		313

@class CBQIFImporter;

static void *CBImporterAccountsChangeContext = @"CBImporterAccountsChangeContext";
static void *CBImporterLabelsChangeContext = @"CBImporterLabelsChangeContext";

NSString *CBImportViewControllerWillShowProgressViewNotification = @"CBImportViewControllerWillShowProgressViewNotification";
NSString *CBImportViewControllerDidShowProgressViewNotification = @"CBImportViewControllerDidShowProgressViewNotification";
NSString *CBImportViewControllerWillShowStandardViewNotification = @"CBImportViewControllerWillShowStandardViewNotification";
NSString *CBImportViewControllerDidShowStandardViewNotification = @"CBImportViewControllerDidShowStandardViewNotification";
NSString *CBImportViewControllerWillChangeScreenNotification = @"CBImportViewControllerWillChangeScreenNotification";
NSString *CBImportViewControllerDidChangeScreenNotification = @"CBImportViewControllerDidChangeScreenNotification";


@interface CBImportViewController (Private)

- (void)setupIfNeeded;

- (void)setMenuForPopUpCell:(NSPopUpButtonCell *)cell
			   withSelected:(id)selected
			  possibleTypes:(NSArray *)possibleTypes
		   possibleAccounts:(NSArray *)possibleAccounts;

- (id)objectAtMenuIndex:(int)locateIndex
	  withPossibleTypes:(NSArray *)possibleTypes
	   possibleAccounts:(NSArray *)possibleAccounts;

- (void)setSelectedLabel:(CBImportLabel *)label;

- (void)importerWillRead:(NSNotification *)notification;
- (void)importerFinishedRead:(NSNotification *)notification;
- (void)importerProgress:(NSNotification *)notification;
- (void)importerFinished:(NSNotification *)notification;

- (void)showProgress:(float)percent withTitle:(NSString *)title;
- (void)hideProgress;

- (BOOL)needsToDisplayLabels;
- (BOOL)needsToDisplayQIFOptions;
- (BOOL)needsToDisplayErrors;

- (BOOL)showingAccounts;
- (BOOL)showingLabels;
- (BOOL)showingQIFOptions;
- (IBAction)showAccounts:(id)sender;
- (IBAction)showLabels:(id)sender;
- (IBAction)showQIFOptions:(id)sender;
- (IBAction)showQIFOptions:(id)sender;
- (void)showErrors:(id)sender;
- (void)showItemAtTabIndex:(int)index;

- (void)complete:(id)sender;

@end

@implementation CBImportViewController

+ (NSString *)nibName {
	return @"ImportView";
}

- (id)init {
	if (self = [super init]) {
		previousTabIndex = -1;
		currentTabIndex = -1;
		nextTabIndex = -1;
		
		colorTitles = [COLOR_LIST_TITLE_ARRAY retain];
		colors = [COLOR_LIST_COLOR_ARRAY retain];
	}
	return self;
}

- (void)awakeFromNib {
	
	NSString *title;
	NSColor *color;
	NSEnumerator *titleEnumerator = [colorTitles reverseObjectEnumerator];
	NSEnumerator *colorEnumerator = [colors reverseObjectEnumerator];
	while ((title = [titleEnumerator nextObject]) && (color = [colorEnumerator nextObject])) {
		FSColoredMenuItem *newItem = [[[FSColoredMenuItem alloc] init] autorelease];
		[newItem setTitle:title];
		[newItem setColor:color];
		[colorMenu insertItem:newItem atIndex:0];
	}
	
	//[self showAccounts:nil];
	[progressIndicator setUsesThreadedAnimation:YES];

	// bind if an importer was set before the nib was loaded
	if (importer && [importer isKindOfClass:[CBQIFImporter class]]) {
		[alterDatesSwitch bind:@"value"
					  toObject:importer
				   withKeyPath:@"dayMonthSwitched"
					   options:nil];		
	}
	
	// display things if the importer's already done some stuff
	if (importer && [importer readComplete]) { [self importerFinishedRead:nil]; }
}

- (void)setupIfNeeded {
	if (setup == FALSE && importer && [importer readComplete]) {
		[self showAccounts:nil];
		setup = TRUE;
	}
}

- (void)dealloc {
	[self setImporter:nil];
	[colors release];
	[colorTitles release];
	[super dealloc];
}

#pragma mark getter/setter methods
// ----------------------------------------------------------------------------------------------------
// getter/setter methods
// ----------------------------------------------------------------------------------------------------

- (CBImporter *)importer {
	return importer;
}

- (void)setImporter:(CBImporter *)anImporter {
	if (importer != anImporter) {
		[self willChangeValueForKey:@"importer"];
		[importer release];
		importer = [anImporter retain];
		[self didChangeValueForKey:@"importer"];
	}	
}

- (void)setSelectedLabel:(CBImportLabel *)label {
	if (selectedLabel != label) {
		[selectedLabel release];
		selectedLabel = [label retain];
	}
}

- (BOOL)canRespond {
	return ([tabViewContainer superview] == [self view] ||
			tabViewContainer == willShowView);
}
- (NSSize)preferredContentSize {
	if ([tabViewContainer superview] == [self view] ||
		tabViewContainer == willShowView) {
		return NSMakeSize(STANDARD_WIDTH, STANDARD_HEIGHT);
	} else if ([progressView superview] == [self view] ||
			   progressView == willShowView) {
		return NSMakeSize(PROGRESS_WIDTH, PROGRESS_HEIGHT);		
	} else {
		return NSZeroSize;
	}
}

- (id)delegate {
	return delegate;
}

- (void)setDelegate:(id)del {
	delegate = del;
}

- (CBImportViewControllerContinueButtonType)continueButton {
	if ([self lastScreen] && ![[self importer] importComplete]) {
		return CBImportViewControllerImportButton;
	} else if ([self lastScreen] && [[self importer] importComplete]) {
		return CBImportViewControllerCompleteButton;
	} else {
		return CBImportViewControllerContinueButton;
	}
}

- (CBImportViewControllerGoBackButtonType)goBackButton {
	if ([self firstScreen] || [[self importer] importComplete]) {
		return CBImportViewControllerCancelButton;
	} else {
		return CBImportViewControllerGoBackButton;
	}
}

#pragma mark watch changes internally
// ----------------------------------------------------------------------------------------------------
// watch changes internally
// ----------------------------------------------------------------------------------------------------

- (void)willChangeValueForKey:(NSString *)key {
	if ([key isEqualToString:@"importer"]) {
		[alterDatesSwitch unbind:@"value"];
		[importer removeObserver:self forKeyPath:@"accounts"];
		[importer removeObserver:self forKeyPath:@"labels"];
		[[NSNotificationCenter defaultCenter] removeObserver:self name:CBImporterWillBeginReadingNotification object:[self importer]];
		[[NSNotificationCenter defaultCenter] removeObserver:self name:CBImporterDidFinishReadingNotification object:[self importer]];
		[[NSNotificationCenter defaultCenter] removeObserver:self name:CBImporterDidProgressImportingNotification object:[self importer]];
		[[NSNotificationCenter defaultCenter] removeObserver:self name:CBImporterDidFinishImportingNotification object:[self importer]];
	}
	[super willChangeValueForKey:key];
}

- (void)didChangeValueForKey:(NSString *)key {
	if ([key isEqualToString:@"importer"]) {
		[accountsTable reloadData];
		[labelsTable reloadData];
		if (importer) {
			if ([importer isKindOfClass:[CBQIFImporter class]]) {
				[alterDatesSwitch bind:@"value"
							  toObject:importer
						   withKeyPath:@"dayMonthSwitched"
							   options:nil];
			}
			[importer addObserver:self forKeyPath:@"accounts" options:0 context:CBImporterAccountsChangeContext];
			[importer addObserver:self forKeyPath:@"labels" options:0 context:CBImporterLabelsChangeContext];
			[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(importerWillRead:) name:CBImporterWillBeginReadingNotification object:[self importer]];
			[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(importerFinishedRead:) name:CBImporterDidFinishReadingNotification object:[self importer]];
			[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(importerProgress:) name:CBImporterDidProgressImportingNotification object:[self importer]];
			[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(importerFinished:) name:CBImporterDidFinishImportingNotification object:[self importer]];
		}
		// display things if the importer's already done some stuff
		if (importer && [importer readComplete]) { [self importerFinishedRead:nil]; }
	}
	[super didChangeValueForKey:key];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
	if (context == CBImporterAccountsChangeContext) {
		[accountsTable reloadData];
	} else if (context == CBImporterLabelsChangeContext) {
		[labelsTable reloadData];
	}
}

#pragma mark listening to importer notifications
// ----------------------------------------------------------------------------------------------------
// listening to importer notifications
// ----------------------------------------------------------------------------------------------------

- (void)importerWillRead:(NSNotification *)notification {
	[self view]; // make sure the nib file is loaded
	[self showProgress:0 withTitle:FSLocalizedString(@"Reading file...", nil)];
}

- (void)importerFinishedRead:(NSNotification *)notification {
	[self setupIfNeeded];
	if ([[importer errors] count]) {
		if ([self needsToDisplayErrors]) { [self showErrors:nil]; }		
		[importer clearErrors];
	}
	[self hideProgress];
}

- (void)importerProgress:(NSNotification *)notification {
	[self view]; // make sure the nib file is loaded
	[self showProgress:[[[notification userInfo] objectForKey:@"CBPercent"] floatValue] withTitle:[[notification userInfo] objectForKey:@"CBDescription"]];
}

- (void)importerFinished:(NSNotification *)notification {
	if ([[importer errors] count]) {
		currentTabIndex = nextTabIndex = previousTabIndex = -1;
		if ([self needsToDisplayErrors]) {
			[self showErrors:nil];
			[self hideProgress];
		} else {
			[self complete:nil];			
		}
		[importer clearErrors];
	} else {
		[self complete:nil];
	}
}

#pragma progress
// ----------------------------------------------------------------------------------------------------
// progress
// ----------------------------------------------------------------------------------------------------

- (void)showProgress:(float)percent withTitle:(NSString *)title {
	
	if ([tabViewContainer superview]) { [tabViewContainer removeFromSuperview]; }
	
	[progressTitle setStringValue:title];
	if (percent == 0) {
        [progressIndicator setIndeterminate:YES];
		[progressIndicator startAnimation:nil];
	} else {
		[progressIndicator stopAnimation:nil];
        [progressIndicator setIndeterminate:NO];
		[progressIndicator setDoubleValue:percent];
		[progressIndicator displayIfNeeded];
	}
	
	willShowView = progressView;
	[[NSNotificationCenter defaultCenter] postNotificationName:CBImportViewControllerWillShowProgressViewNotification object:self];
	willShowView = nil;
	
	NSRect viewFrame = [[self view] frame];
	NSRect movedFrame = [progressView frame];
	movedFrame.origin.x = round((float)(viewFrame.size.width - movedFrame.size.width) / 2.0);
	movedFrame.origin.y = round((float)(viewFrame.size.height - movedFrame.size.height) / 2.0);
	[progressView setFrame:movedFrame];
	if (![progressView superview]) { [[self view] addSubview:progressView]; }

	[[NSNotificationCenter defaultCenter] postNotificationName:CBImportViewControllerDidShowProgressViewNotification object:self];
	
	[[self view] display]; // forces display regardless of resize
}

- (void)hideProgress {
	if ([progressView superview]) { [progressView removeFromSuperview]; }	
	[progressIndicator stopAnimation:nil];
	
	willShowView = tabViewContainer;
	[[NSNotificationCenter defaultCenter] postNotificationName:CBImportViewControllerWillShowStandardViewNotification object:self];
	willShowView = nil;
	
	NSRect viewFrame = [[self view] frame];
	viewFrame.origin = NSMakePoint(0, 0);
	[tabViewContainer setFrame:viewFrame];
	if (![tabViewContainer superview]) { [[self view] addSubview:tabViewContainer]; }

	[[NSNotificationCenter defaultCenter] postNotificationName:CBImportViewControllerDidShowStandardViewNotification object:self];
	
	[[self view] display]; // forces display regardless of resize
}

#pragma mark interface methods
// ----------------------------------------------------------------------------------------------------
// interface methods
// ----------------------------------------------------------------------------------------------------

- (BOOL)firstScreen {
	return previousTabIndex == -1;
}
- (BOOL)lastScreen {
	return nextTabIndex == -1;		
}

- (void)showPreviousScreen:(id)sender {
	if ([self goBackButton] == CBImportViewControllerCancelButton) {
		if (delegate && [delegate respondsToSelector:@selector(importViewControllerDidCancel:)]) {
			[delegate importViewControllerDidCancel:self];
		}		
	} else if ([self goBackButton] == CBImportViewControllerGoBackButton) {
		[self showItemAtTabIndex:previousTabIndex];
	}
}

- (void)showNextScreen:(id)sender {
	if ([self continueButton] == CBImportViewControllerImportButton) {
		if (delegate && [delegate respondsToSelector:@selector(importViewControllerAcceptedImport:)]) {
			[delegate importViewControllerAcceptedImport:self];
		}		
	} else if ([self continueButton] == CBImportViewControllerCompleteButton) {
		[self complete:nil];
	} else if ([self continueButton] == CBImportViewControllerContinueButton) {
		[self showItemAtTabIndex:nextTabIndex];		
	}
}

- (BOOL)needsToDisplayLabels {
	return [[importer labels] count] != 0;
}

- (BOOL)needsToDisplayQIFOptions {
	return ([importer isKindOfClass:[CBQIFImporter class]] &&
			[[NSUserDefaults standardUserDefaults] boolForKey:CBShowQIFOptionsScreenPreferenceKey]);
}

- (BOOL)showingAccounts {
	return (currentTabIndex == ACCOUNTS_TAB);
}
- (BOOL)showingLabels {
	return (currentTabIndex == LABELS_TAB);
}
- (BOOL)showingQIFOptions {
	return (currentTabIndex == QIF_OPTIONS_TAB);
}
- (BOOL)needsToDisplayErrors {
	return 	[[NSUserDefaults standardUserDefaults] boolForKey:CBShowImportingErrorsAndWarningsPreferenceKey];
}

- (void)showItemAtTabIndex:(int)index {
	switch (index) {
		case ACCOUNTS_TAB:
			[self showAccounts:nil];
			break;
		case LABELS_TAB:
			[self showLabels:nil];
			break;
		case QIF_OPTIONS_TAB:
			[self showQIFOptions:nil];
			break;
		default:
			// fall back on simply ending
			[self complete:nil];
			break;
	}	
}

- (IBAction)showAccounts:(id)sender {
	[[NSNotificationCenter defaultCenter] postNotificationName:CBImportViewControllerWillChangeScreenNotification object:self];
	currentTabIndex = ACCOUNTS_TAB;
	previousTabIndex = -1;
	if ([self needsToDisplayLabels]) { nextTabIndex = LABELS_TAB; }
	else if ([self needsToDisplayQIFOptions]) { nextTabIndex = QIF_OPTIONS_TAB; }
	else { nextTabIndex = -1; }
	
	[tabView selectTabViewItemAtIndex:currentTabIndex];
	[[NSNotificationCenter defaultCenter] postNotificationName:CBImportViewControllerDidChangeScreenNotification object:self];
}

- (IBAction)showLabels:(id)sender {
	[[NSNotificationCenter defaultCenter] postNotificationName:CBImportViewControllerWillChangeScreenNotification object:self];
	currentTabIndex = LABELS_TAB;
	previousTabIndex = ACCOUNTS_TAB;
	if ([self needsToDisplayQIFOptions]) { nextTabIndex = QIF_OPTIONS_TAB; }
	else { nextTabIndex = -1; }
	
	[tabView selectTabViewItemAtIndex:currentTabIndex];
	[[NSNotificationCenter defaultCenter] postNotificationName:CBImportViewControllerDidChangeScreenNotification object:self];
}

- (IBAction)showQIFOptions:(id)sender {
	[[NSNotificationCenter defaultCenter] postNotificationName:CBImportViewControllerWillChangeScreenNotification object:self];
	currentTabIndex = QIF_OPTIONS_TAB;
	if ([self needsToDisplayLabels]) { previousTabIndex = LABELS_TAB; }
	else { previousTabIndex = ACCOUNTS_TAB; }
	nextTabIndex = -1;
	
	[tabView selectTabViewItemAtIndex:currentTabIndex];
	[[NSNotificationCenter defaultCenter] postNotificationName:CBImportViewControllerDidChangeScreenNotification object:self];
}

- (void)showErrors:(id)sender {
	[[NSNotificationCenter defaultCenter] postNotificationName:CBImportViewControllerWillChangeScreenNotification object:self];
	previousTabIndex = currentTabIndex;
	nextTabIndex = currentTabIndex;
	
	// don't store the currentTabIndex
	[tabView selectTabViewItemAtIndex:ERRORS_TAB];
	NSArray *errors = [[[self importer] errors] arrayByPerformingSelectorOnObjects:@selector(localizedDescription)];
	NSString *errorString = [errors componentsJoinedByString:@"\n\n"];
	[errorTextField setStringValue:errorString];		
	[[NSNotificationCenter defaultCenter] postNotificationName:CBImportViewControllerDidChangeScreenNotification object:self];
}

- (void)complete:(id)sender {
	currentTabIndex = nextTabIndex = previousTabIndex = -1;
	if (delegate && [delegate respondsToSelector:@selector(importViewControllerHasCompletedAllScreens:)]) {
		[delegate importViewControllerHasCompletedAllScreens:self];
	}
}

#pragma mark IB interface actions
// ----------------------------------------------------------------------------------------------------
// IB interface actions
// ----------------------------------------------------------------------------------------------------

- (IBAction)colorChange:(id)sender {
	CBImportLabel *label = selectedLabel;
	if (label) { [label setColor:[sender color]]; }
	[labelsTable reloadData];
}

- (IBAction)showColorPanel:(id)sender {
	if (!panel) {
		panel = [[NSColorPanel alloc] init];
		[panel setContinuous:YES];
		[panel setTarget:self];
		[panel setAction:@selector(colorChange:)];
	}
	[panel setColor:[selectedLabel color]];
	[panel makeKeyAndOrderFront:nil];
}

- (IBAction)doNotDisplayQIFOptionsAgainClick:(id)sender {
	[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:FALSE] forKey:CBShowQIFOptionsScreenPreferenceKey];

	NSWindow *modalWindow = [[self view] window];
	if ([modalWindow attachedSheet]) { modalWindow = nil; }
	NSBeginAlertSheet(FSLocalizedString(@"You will not be asked again.", nil),
					  FSLocalizedString(@"OK", nil),
					  nil,
					  nil,
					  modalWindow,
					  nil,
					  nil,
					  nil,
					  nil,
					  FSLocalizedString(@"Your preference has been set, and you will not be asked aobut these options again.  To finish your import, click OK and then click Import.", nil));
}

- (IBAction)moreInformationClick:(id)sender {
	[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:QIF_INFORMTION_URL]];
}

#pragma mark table view data source / delegate
// ----------------------------------------------------------------------------------------------------
// table view data source / delegate
// ----------------------------------------------------------------------------------------------------

- (void)setMenuForPopUpCell:(NSPopUpButtonCell *)cell
			   withSelected:(id)selected
			  possibleTypes:(NSArray *)possibleTypes
		   possibleAccounts:(NSArray *)possibleAccounts {
	
	NSMenu *menu = [[[NSMenu alloc] init] autorelease];
	NSMenuItem *selectedMenuItem = nil;
	
	Class type;
	NSEnumerator *possibleTypesEnumerator = [possibleTypes objectEnumerator];
	while (type = [possibleTypesEnumerator nextObject]) {
		NSMenuItem *item = [[[NSMenuItem alloc] init] autorelease];
		[item setTitle:[NSString stringWithFormat:FSLocalizedString(@"Create new %@", nil), [type name]]];
		[menu addItem:item];
		if ([selected isEqualTo:type]) { selectedMenuItem = item; }
	}
		
	if ([possibleTypes count] && [possibleAccounts count]) {
		[menu addItem:[NSMenuItem separatorItem]];
	}
	
	CBAccount *account;
	NSEnumerator *possibleAccountsEnumerator = [possibleAccounts objectEnumerator];
	while (account = [possibleAccountsEnumerator nextObject]) {
		NSMenuItem *item = [[[NSMenuItem alloc] init] autorelease];
		[item setTitle:[NSString stringWithFormat:FSLocalizedString(@"Add to %@", nil), [account name]]];
		[menu addItem:item];
		if ([selected isEqualTo:account]) { selectedMenuItem = item; }
	}

	[cell setMenu:menu];
	if (selectedMenuItem) { [cell selectItem:selectedMenuItem]; }
}

- (id)objectAtMenuIndex:(int)locateIndex
	  withPossibleTypes:(NSArray *)possibleTypes
	   possibleAccounts:(NSArray *)possibleAccounts {
	
	int index = 0;
	Class type;
	NSEnumerator *possibleTypesEnumerator = [possibleTypes objectEnumerator];
	while (type = [possibleTypesEnumerator nextObject]) {
		if (index == locateIndex) { return type; }
		index++;
	}
	
	if ([possibleTypes count] && [possibleAccounts count]) { index++; }
	
	CBAccount *account;
	NSEnumerator *possibleAccountsEnumerator = [possibleAccounts objectEnumerator];
	while (account = [possibleAccountsEnumerator nextObject]) {
		if (index == locateIndex) { return account; }
		index++;
	}
	return nil;
}

- (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(int)row {
	if (tableView == accountsTable) {
		if ([[tableColumn identifier] isEqualToString:@"action"]) {
			CBImportAccount *importAccount = [[importer accounts] objectAtIndex:row];
			id object = [importAccount mergeAccount];
			if (!object) { object = [importAccount createAccount]; }
			if (!object) { object = [[importAccount possibleTypes] firstObject]; [importAccount setCreateAccount:object]; } // set the default if needed
			
			[self setMenuForPopUpCell:cell
						 withSelected:object
						possibleTypes:[importAccount possibleTypes]
					 possibleAccounts:[importAccount possibleAccounts]];
		}
	} else if (tableView == labelsTable) {
		CBImportLabel *label = [[importer labels] objectAtIndex:row];
		
		if ([[tableColumn identifier] isEqualToString:@"name"]) {
			NSColor *color = [label color];
			[cell setOvalColor:color];
		} else if ([[tableColumn identifier] isEqualToString:@"action"]) {
			NSColor *color = [[[importer labels] objectAtIndex:row] color];
			if ([colors containsObject:color]) { [otherMenuItem setColor:nil]; }
			else { [otherMenuItem setColor:color]; }
		}		
	}
}


- (void)tableViewSelectionIsChanging:(NSNotification *)notification {
	if ([notification object] == labelsTable) {
		if ([labelsTable selectedRow] != -1) { [self setSelectedLabel:[[importer labels] objectAtIndex:[labelsTable selectedRow]]]; }
		else { [self setSelectedLabel:nil]; }
		
		// ensure the "other color" is right before the popup appears
		if ([colors containsObject:[selectedLabel color]]) { [otherMenuItem setColor:nil]; }
		else { [otherMenuItem setColor:[selectedLabel color]]; }
		
		if (panel) { [panel close]; }		
	}
}

- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(int)row {
	if ([[tableColumn identifier] isEqualToString:@"name"]) {
		return NO;		
	} else {
		return YES;
	}
}

- (int)numberOfRowsInTableView:(NSTableView *)tableView {
	if (tableView == accountsTable) {
		return [[importer accounts] count];
	} else if (tableView == labelsTable) {
		return [[importer labels] count];
	}
	return 0;
}

- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row {

	if (tableView == accountsTable) {
		if ([[tableColumn identifier] isEqualToString:@"flag"]) {
			return [NSNumber numberWithBool:[(CBImportAccount *)[[importer accounts] objectAtIndex:row] import]];
		} else if ([[tableColumn identifier] isEqualToString:@"name"]) {
			return [(CBImportAccount *)[[importer accounts] objectAtIndex:row] name];
		}		
	} else if (tableView == labelsTable) {
		if ([[tableColumn identifier] isEqualToString:@"flag"]) {
			return [NSNumber numberWithBool:[(CBImportLabel *)[[importer labels] objectAtIndex:row] import]];
		} else if ([[tableColumn identifier] isEqualToString:@"name"]) {
			return [(CBImportLabel *)[[importer labels] objectAtIndex:row] name];
		} else if ([[tableColumn identifier] isEqualToString:@"action"]) {
			int index;
			NSColor *color;
			NSMenuItem *menuItem;
			NSEnumerator *menuItemEnumerator;
			
			color = [[[importer labels] objectAtIndex:row] color];
			if (color) {
				index = 0;
				menuItemEnumerator = [[[[tableColumn dataCell] menu] itemArray] objectEnumerator];
				while (menuItem = [menuItemEnumerator nextObject]) {
					if ([menuItem isKindOfClass:[FSColoredMenuItem class]] &&
						[[(FSColoredMenuItem *)menuItem color] isEqualTo:color]) {
						return [NSNumber numberWithInt:index];
					}
					index++;
				}		
			}
			
			index = [[[tableColumn dataCell] menu] numberOfItems]-1;
			return [NSNumber numberWithInt:index];	
		}		
	}
	
	return nil;
}

- (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(int)row {
	
	if (tableView == accountsTable) {
		if ([[tableColumn identifier] isEqualToString:@"flag"]) {
			[(CBImportAccount *)[[importer accounts] objectAtIndex:row] setImport:[object boolValue]];
		} else if ([[tableColumn identifier] isEqualToString:@"action"]) {

			CBImportAccount *importAccount = [[importer accounts] objectAtIndex:row];
			id value = [self objectAtMenuIndex:[object intValue]
							 withPossibleTypes:[importAccount possibleTypes]
							  possibleAccounts:[importAccount possibleAccounts]];
			
			if ([value isKindOfClass:[CBAccount class]]) {
				[importAccount setMergeAccount:value];
			} else if ([value class] == value) { // is it a class object
				[importAccount setCreateAccount:value];
			}
		}
	} else if (tableView == labelsTable) {
		if ([[tableColumn identifier] isEqualToString:@"flag"]) {
			[(CBImportLabel *)[[importer labels] objectAtIndex:row] setImport:[object boolValue]];
		} else if ([[tableColumn identifier] isEqualToString:@"action"]) {
			int index = [object intValue];
			NSMenuItem *menuItem = [[[tableColumn dataCell] menu] itemAtIndex:index];
			if ([menuItem isKindOfClass:[FSColoredMenuItem class]]) {
				NSColor *color = [(FSColoredMenuItem *)menuItem color];
				[[[importer labels] objectAtIndex:row] setColor:color];
			}
		}		
	}
}

@end
